package com.synygy.bdviewer.dao;

import org.hibernate.type.NullableType;
import org.hibernate.Hibernate;

import java.util.List;
import java.util.ArrayList;

import com.synygy.bdviewer.util.QueryParam;
import com.synygy.bdviewer.model.STIObject;


public class HibernateContactFinderQueryBuilder {
    private List<String> parameters;
    private List<NullableType> types;
    private boolean count;
    private STIObject filter = new STIObject();
    private QueryParam queryParam;

    public String buildHql() {
        parameters = new ArrayList<String>();
        types = new ArrayList<NullableType>();
        StringBuilder hql = new StringBuilder();
        addCountClause(hql);
        hql.append("from STIObject target where 1=1 ");
//        if (filter.getDate() != null) {
//            addMatchingCondition(hql, filter.getId().toString(), "id");
//        }
        addMatchingCondition(hql, filter.getVersion(), "version");
        addMatchingCondition(hql, filter.getDefectLogged(), "defectLogged");
        addMatchingCondition(hql, filter.getModuleOrFeature(), "moduleOrFeature");
        addMatchingCondition(hql, filter.getPersonResponsible(), "personResponsible");
        addMatchingCondition(hql, filter.getRootCause(), "rootCause");
//        if (filter.getDate() != null) {
//            addMatchingCondition(hql, filter.getDate().toString(), "date");
//        }
//
//        addMatchingCondition(hql, Boolean.toString(filter.isSuccess()), "success");

        addOrderByClause(hql);
        return hql.toString();
    }

    private void addCountClause(StringBuilder hql) {
        if (count) {
            hql.append("select count(*) ");
        }
    }

    private void addMatchingCondition(StringBuilder hql, String value, String name) {
        if (value != null) {
            hql.append("and upper(target.");
            hql.append(name);
            hql.append(") like (?)");
            parameters.add("%" + value.toUpperCase() + "%");
            types.add(Hibernate.STRING);
        }
    }

    private void addOrderByClause(StringBuilder hql) {
        if (!count && queryParam != null && queryParam.hasSort()) {
            hql.append("order by upper(target.");
            hql.append(queryParam.getSort());
            hql.append(") ");
            hql.append(queryParam.isSortAsc() ? "asc" : "desc");
        }
    }

    public void setQueryParam(QueryParam queryParam) {
        this.queryParam = queryParam;
    }

    public void setFilter(STIObject filter) {
        if (filter == null) {
            throw new IllegalArgumentException("Null value not allowed.");
        }
        this.filter = filter;
    }

    public void setCount(boolean count) {
        this.count = count;
    }

    public String[] getParameters() {
        return parameters.toArray(new String[0]);
    }

    public NullableType[] getTypes() {
        return types.toArray(new NullableType[0]);
    }
}
